package com.example.mq.mqserver.core;

import java.io.Serializable;
import java.util.Arrays;
import java.util.UUID;

/**
 * @Description: 表示一条要传递的消息$
 * @Author: liudong
 */
//一个Message主要包含了两个部分，属性名（BasicProperties），正文（byte[])

/**
 * Message表示一个要传递的对象
 * 此处的Message对象，需要能够在网络上传输，并且也能写入到文件中
 * 此处就要针对Message进行序列化和反序列化
 * 此处使用标准库自带的 序列化/反序列化 操作
 * 通过引用Serualizable这个接口来实现
 */


public class Message implements Serializable {
    //用来验证版本的，实际代码中是不断更新修改的，是需要手动更改的
    //如果发现，代码和序列化的数据不匹配，就不允许进行反序列化，提示数据有问题
    private static final long serialVersionUID = 1L;

    //核心属性
    private BasicProperties basicProperties = new BasicProperties();//属性
    private byte[] body;//正文


    //其他属性
    //Message后续会存储到文件中（前提是持久化存储）
    //一个文件中会存储很多消息，如何找到某个消息在文件中的具体位置？
    //通过使用下面两个偏移量来表示
    //这两个属性不需要序列化
    //这两个属性主要是为了让内存上的Message找到硬盘上Message对应的位置
    //被transient修饰的关键字不会被序列化
    private transient long offsetBeg = 0;//消息数据的开头距离文件开头的偏移
    private transient long offsetEnd = 0;//结尾距离文件开头的位置偏移量（字节）

    //这个属性表示在文件中是否是有效的(针对文件中的消息，如果删除，使用逻辑删除的方式）
    //0x1表示有效 0x0表示无效
    private byte isvalid = 0x1;

    //创建一个工厂方法，让工厂方法帮我们封装一下创建Message对象的进程
    //这个方法中创建的Message对象，会自动生成唯一的MessageId
    public static Message createMessageWithId(String routingKey, BasicProperties basicProperties, byte[] body) {
        Message message = new Message();
        if (basicProperties != null) {
            message.setBasicProperties(basicProperties);
        }
        //如果MessageId和basicMessageWithId里的MessageId冲突，以外面的为主，把里面的覆盖掉
        //生成的MessageId以M-为前缀，主要是为了和后面其他的id作区分
        message.setMessageId("M-" + UUID.randomUUID());

        //如果routingKey和basicMessageWithId里的routingKey冲突，以外面的为主，把里面的覆盖掉
        //先把body和basicProperties先设置出来，他俩是核心内容
        //offsetBeg、offsetEnd、isvalid则是消息持久化的时候才会用到
        //这里指的是在内存中创建了一个Message对象
        message.setRoutingKey(routingKey);
        message.body = body;
        return message;
    }

    public String getMessageId() {
        return basicProperties.getMessageId();
    }

    public void setMessageId(String messageId) {
        basicProperties.setMessageId(messageId);
    }

    public String getRoutingKey() {
        return basicProperties.getRoutingKey();
    }

    public void setRoutingKey(String routingKey) {
        basicProperties.setRoutingKey(routingKey);
    }

    public int getDeliverMode() {
        return basicProperties.getDeliverMode();
    }

    public void setDeliverMode(int mode) {
        basicProperties.setDeliverMode(mode);
    }

    public BasicProperties getBasicProperties() {
        return basicProperties;
    }

    public void setBasicProperties(BasicProperties basicProperties) {
        this.basicProperties = basicProperties;
    }

    public byte[] getBody() {
        return body;
    }

    public void setBody(byte[] body) {
        this.body = body;
    }

    public long getOffsetBeg() {
        return offsetBeg;
    }

    public void setOffsetBeg(long offsetBeg) {
        this.offsetBeg = offsetBeg;
    }

    public long getOffsetEnd() {
        return offsetEnd;
    }

    public void setOffsetEnd(long offsetEnd) {
        this.offsetEnd = offsetEnd;
    }

    public byte getIsvalid() {
        return isvalid;
    }

    public void setIsvalid(byte isvalid) {
        this.isvalid = isvalid;
    }

    @Override
    public String toString() {
        return "Message{" +
                "basicProperties=" + basicProperties +
                ", body=" + Arrays.toString(body) +
                ", offsetBeg=" + offsetBeg +
                ", offsetEnd=" + offsetEnd +
                ", isvalid=" + isvalid +
                '}';
    }
}
